#ifndef __SHIP_HEADER
#define __SHIP_HEADER

#include "cost_classes.h"
#include <vector>
#include <array>
#include <string>

struct StructuralDamages {
	bool noTurnLeft;
	bool noTurnRight;
	int speedLoss;
	int heightLoss;
	std::vector<bool> noControlTower;
};

struct ShipStatus {
	int actualHp;
	StructuralDamages dmg;
	int thrust;
	std::vector<int> controlTowers;
};

struct SlotStatus {
	int actualHp;
	int loadout;
};

class ShipTemplate;
namespace Json { class Value; }

class Ship : public CostChanger {
	public:
		// Builds the whole object tailored to the ship
		Ship( std::string _name, int thrust, const ShipTemplate & _ship );

		Ship( const Json::Value & _ship, const ShipTemplate & _ts, std::string _name = "");

		Json::Value convertToJson(bool _templateToo = true) const;

		// Thrust
		void setThrust(int _thrust);
		// Towers
		void setControlTowerLoadout(int _tower, int _loadout);
		// Slots
		void setSlotLoadout( int _side, int _slot, int _loadout );

		// Decreases actualHp by one
		// Returns: True if afterwards actualHp is 0, false otherwise
		bool reduceHp();

		// Resets actualHp to the max value
		void resetHp();
		void resetSidesHp();
		void resetSideHp(int _side);
		void resetSlotHp(int _side, int _slot);

		// Sets actualHp to value
		void setHp( int _hp );
		void setSidesHp( int _hp );
		void setSideHp( int _side, int _hp );
		void setSlotHp( int _side, int _slot, int _hp );

		// Modifies X and Y with respect to _dir
		void move( int _dir );
		void ascent();
		void descent();

		// Sets the position of the ship
		void setPosition( int _x, int _y );
		void setDirection( int _dir );
		void setHeight( int _h );

		// Applies a given damage on the ship
		// Returns: True if the particular damage was already at max, false otherwise
		bool damageTurnLeft();
		bool damageTurnRight();
		bool damageMaxSpeed();
		bool damageMaxHeight();
		bool damageControlTower(int _tower);

		// SUMMARIES -----------

		// Name, Template Name, Cost
		std::array<std::string,3> getSummary() const;
		// Side, Dirs ( easier ), Cannons?, Loadout, Loadout Cost
		std::vector<std::array<std::string,5>> getSlotLoadoutSummaries() const;
		// Side, Dirs, ActualHP, TotalHp
		std::vector<std::array<std::string,4>> getSlotStatusSummaries() const;

		// GETTERS -------------

		int getThrust() const;

		int getActualHp() const;
		StructuralDamages getDmg() const;

		std::vector<int> getTowerLoadouts() const;
		std::vector<bool> getTowerStatuses() const;

		int getX() const;
		int getY() const;
		int getH() const;
		int getDirection() const;

		int getLoadoutCost() const;
		const ShipTemplate * getShipTemplate() const;

		// Resets structural damages to none
		void resetStructuralDamages();

		// The name of the ship
		std::string name;
	private:
		const ShipTemplate & ownShipTemplate;

		ShipStatus hull;
		std::array<std::vector<SlotStatus>,6> sides;

		// Position of the ship and facing
		int x, y, h, direction;

		friend class Deployment;
};

#endif
